package appapi.service.impl;

import appapi.Request.EquiPageReq;
import appapi.Request.InspectionPageReq;
import appapi.Request.record.MonthRecPageReq;
import appapi.Vo.record.*;
import appapi.dao.*;
import appapi.dto.AnnexType;
import appapi.dto.GetAlarmPageDto;
import appapi.dto.bridge.MonthExportDto;
import appapi.entity.Zhongjiao.AlarmledgerEntity;
import appapi.entity.Zhongjiao.AnnexDto;
import appapi.entity.app.AnnexEntity;
import appapi.dto.MonthRecModel;
import appapi.entity.app.RectificationEntity;
import appapi.entity.basic.SysConfigEntity;
import appapi.entity.basic.UserInfo;
import appapi.entity.record.MonthInspectionModel;
import appapi.entity.record.MonthdetailEntity;
import appapi.utils.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.rmi.CORBA.Util;
import javax.xml.crypto.Data;

import appapi.entity.record.MonthInspectionEntity;
import appapi.service.MonthinspectionService;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 请求对象
 *
 * @author luocheng
 * @version 1.0
 * @date 2023/06/01 11:45
 */
@Service
public class MonthinspectionServiceImpl implements MonthinspectionService {

    @Resource
    private MonthinspectionMapper monthinspectionMapper;
    @Resource
    private MonthdetailMapper monthdetailMapper;
    @Autowired
    private RectificationMapper rectificationMapper;
    @Resource
    AnnexMapper annexMapper;
    @Resource
    StaffMapper staffMapper;
    @Resource
    EquipmentMapper equipmentMapper;
    @Resource
    DictionaryMapper dictionaryMapper;
    @Resource
    AlarmledgerMapper alarmledgerMapper;
    @Resource
    SysConfigMapper sysConfigMapper;

    @Override
    public List<Map<String, Object>> SelectListByPage(InspectionPageReq req) {
        return monthinspectionMapper.selectMonthInspectionPage(req);
    }

    @Override
    public PageInfo<MonthRecModel> page(MonthRecPageReq req) {
        if (ObjectUtils.allNotNull(req.getCurrPage(), req.getPageSize())) {
            PageHelper.startPage(req.getCurrPage(), req.getPageSize());
        }
        List<MonthRecModel> list = monthinspectionMapper.queryList(req);
        PageInfo pageInfo = new PageInfo(list);

        return pageInfo;
    }

    @Override
    public List<MonthRecModel> getList(MonthRecPageReq req) {
        List<MonthRecModel> list = monthinspectionMapper.queryList(req);
        return list;
    }

    @Override
    public List<MonthExportDto> getLists(MonthRecPageReq req) {
        List<MonthExportDto> list = monthinspectionMapper.queryLists(req);
        return list;
    }

    @Override
    public List<Map<String, Object>> SelectList(Long equipId) {
        return monthinspectionMapper.selectList(equipId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int InsertInfo(AddMonthRecVo vo) {
        MonthInspectionEntity recEntity = vo.vo2Entity();
        recEntity.setAuditState(0);
        recEntity.setCreateTime(LocalDateTime.now());
        recEntity.setUpdateTime(LocalDateTime.now());
        recEntity.setEditOperator(vo.getOperator());
        //添加月检记录
        int iRet = monthinspectionMapper.insertSelective(recEntity);
        if (iRet > 0) {
            Long monthId = recEntity.getMonthId();
            //添加月检明细
            AddMonthDetail(monthId, vo.getDetailVos());
            //是否需要写整改
            List<String> expList = vo.getDetailVos().stream()
                    .filter(AddMonthDetailVo -> AddMonthDetailVo.getMonthResult() == 1)
                    .map(AddMonthDetailVo::getMonthItem)
                    .collect(Collectors.toList());
            if (expList.size() > 0) {
                //异常，添加整改信息
                List<RectificationEntity> rectList = new ArrayList<>();
                RectificationEntity rectEntity = new RectificationEntity();
                rectEntity.setRectItem(String.join(",", expList));
                rectEntity.setRectRequire(vo.getExpRequire());
                rectEntity.setEquipId(vo.getEquipId());
                rectEntity.setRectState(0);
                rectEntity.setRectAdd(1);
                rectEntity.setRectSource(monthId);
                rectEntity.setRectType(AnnexType.AnnexTypeEnum.monthCheck.getCode());
                rectEntity.setSoutOper(vo.getOperator());
                rectEntity.setRectDate(new Date());
                rectEntity.setCreateTime(LocalDateTime.now());
                rectEntity.setUpdateTime(LocalDateTime.now());
                rectList.add(rectEntity);
                rectificationMapper.insertBatch(rectList);
            }
            //有附件则新增附件
            if (vo.getAnnexUrl().size() > 0) {
                //String[] user = JwtUtil.getUserInfoByJwtToken(request);
                //暂搁置
                List<AnnexEntity> annexCollect = vo.getAnnexUrl().stream().map(annex -> {
                    AnnexEntity dto = new AnnexEntity();
                    dto.setCreateTime(LocalDateTime.now());
                    dto.setUpdateTime(LocalDateTime.now());
                    dto.setAnnexTitle("月检");
                    dto.setAnnexType("monthCheck");
                    dto.setRecId(recEntity.getMonthId());
                    dto.setAnnexUrl(annex);
                    dto.setCreateUser(vo.getCreateUser());
                    return dto;
                }).collect(Collectors.toList());

                annexMapper.insertList(annexCollect);
            }
        }
        return iRet;
    }

    /**
     * 添加月检明细
     *
     * @param monthId
     * @param detailVos
     * @return
     */
    private void AddMonthDetail(Long monthId, List<AddMonthDetailVo> detailVos) {
        List<MonthdetailEntity> entityList = new ArrayList<>();
        for (AddMonthDetailVo vo : detailVos
        ) {
            MonthdetailEntity entity = vo.vo2Entity();
            entity.setMonthId(monthId);
            entity.setAuditState(0);
            entity.setCreateTime(LocalDateTime.now());
            entity.setUpdateTime(LocalDateTime.now());
            entity.setImgUrl(String.join(",", vo.getImgUrl()));
            entityList.add(entity);
        }
        if (entityList.size() > 0) {
            monthdetailMapper.insertList(entityList);
        }
    }


    @Override
    public int UpdateInfo(EditMonthRecVo vo) {
        MonthInspectionEntity recEntity = vo.vo2Entity();
        recEntity.setAuditState(0);
        recEntity.setUpdateTime(LocalDateTime.now());
        recEntity.setEditOperator(vo.getEditOperator());
        //编辑月检记录
        int iRet = monthinspectionMapper.updateByPrimaryKey(recEntity);
        if (iRet > 0) {
            Long monthId = vo.getMonthId();
            //删除明细
            monthdetailMapper.deleteByMonthId(monthId);
            //删除整改信息
            rectificationMapper.deleteByRecId(AnnexType.AnnexTypeEnum.selfCheck.getCode(), monthId);
            //重新月检明细
            EditMonthDetail(vo.getMonthId(), vo.getDetailVos());
            //是否需要写整改
            List<String> expList = vo.getDetailVos().stream()
                    .filter(EditMonthDetailVo -> EditMonthDetailVo.getMonthResult() == 1)
                    .map(EditMonthDetailVo::getMonthItem)
                    .collect(Collectors.toList());
            if (expList.size() > 0) {
                //异常，添加整改信息
                List<RectificationEntity> rectList = new ArrayList<>();
                RectificationEntity rectEntity = new RectificationEntity();
                rectEntity.setRectItem(String.join(",", expList));
                rectEntity.setRectRequire(vo.getExpRequire());
                rectEntity.setEquipId(vo.getEquipId());
                rectEntity.setRectState(0);
                rectEntity.setRectAdd(1);
                rectEntity.setRectSource(monthId);
                rectEntity.setRectType(AnnexType.AnnexTypeEnum.monthCheck.getCode());
                rectEntity.setSoutOper(vo.getOperator());
                rectEntity.setRectDate(new Date());
                rectEntity.setCreateTime(LocalDateTime.now());
                rectEntity.setUpdateTime(LocalDateTime.now());
                rectList.add(rectEntity);
                rectificationMapper.insertBatch(rectList);
            }
            annexMapper.deleteByRecId(AnnexType.AnnexTypeEnum.monthCheck.name(), Collections.singletonList(monthId));
            //有附件则新增附件
            if (vo.getAnnexUrl().size() > 0) {
                //暂搁置
                List<AnnexEntity> annexCollect = vo.getAnnexUrl().stream().map(annex -> {
                    AnnexEntity dto = new AnnexEntity();
                    dto.setCreateTime(LocalDateTime.now());
                    dto.setUpdateTime(LocalDateTime.now());
                    dto.setAnnexTitle("月检");
                    dto.setAnnexType("monthCheck");
                    dto.setRecId(recEntity.getMonthId());
                    dto.setAnnexUrl(annex);
                    dto.setCreateUser(vo.getCreateUser());
                    return dto;
                }).collect(Collectors.toList());

                annexMapper.insertList(annexCollect);
            }
        }
        return iRet;
    }

    /**
     * 编辑时添加月检明细
     *
     * @param detailVos
     * @return
     */
    private void EditMonthDetail(Long monthId, List<EditMonthDetailVo> detailVos) {
        List<MonthdetailEntity> entityList = new ArrayList<>();
        for (EditMonthDetailVo vo : detailVos
        ) {
            MonthdetailEntity entity = vo.vo2Entity();
            entity.setMonthId(monthId);
            entity.setAuditState(0);
            entity.setCreateTime(LocalDateTime.now());
            entity.setUpdateTime(LocalDateTime.now());
            entity.setImgUrl(String.join(",", vo.getImgUrl()));
            entityList.add(entity);
        }
        if (entityList.size() > 0) {
            monthdetailMapper.insertList(entityList);
        }
    }

    @Override
    public int DeleteInfo(List<Long> monthIds) {
        int iRet = monthinspectionMapper.deleteBatch(monthIds);
        if (iRet > 0) {
            //删除明细
            monthdetailMapper.deleteByMonthIdBatch(monthIds);
            //删除整改信息
            rectificationMapper.deleteSourcesBatch(AnnexType.AnnexTypeEnum.selfCheck.getCode(), monthIds);
        }
        return iRet;
    }

    @Override
    public List<Map<String, Object>> SelectMonthInspectionDetail(Long monthId) {
        return monthinspectionMapper.selectMonthMapById(monthId);
    }

    @Override
    public MonthInspectionModel getDetail(Long monthId) {
        MonthInspectionModel model = new MonthInspectionModel();
        MonthInspectionEntity dto = monthinspectionMapper.selectByPrimaryKey(monthId);
        if (dto != null) {
            String json = JSON.toJSONString(dto);
            model = JSON.parseObject(json, new TypeReference<MonthInspectionModel>() {
            });
            List<MonthdetailEntity> monthdetailDtos = monthdetailMapper.selectByMonthId(monthId);
            List<AnnexDto> annexDtos = annexMapper.selectAllByRecId(AnnexType.AnnexTypeEnum.monthCheck.name(), monthId);
            model.setAnnexUrl(annexDtos.stream().map(AnnexDto::getAnnexUrl).collect(Collectors.toList()));
            model.setDetail(monthdetailDtos);
        }
        return model;
    }

    @Override
    public MonthInspWarnVo GetWarn(UserInfo userInfo) {

        Integer warnNum = 0;
        Integer alarmNum = 0;

        MonthInspWarnVo vo = new MonthInspWarnVo();
        //拿到该人员的信息
        Map<String, Object> staffInfo = staffMapper.selectStaffDetail(userInfo.getUserid());
        EquiPageReq req = new EquiPageReq();
        req.setOrgaPathIds(staffInfo.get("orgaPathIds").toString());
        //查到该人员能看到的所有设备
        List<Map<String, Object>> list = equipmentMapper.selectEquiPageList(req);

        List<Long> equipIds = list.stream().map(map -> (Long) map.get("equipId")).collect(Collectors.toList());

        //查到预警天数(指离上次多久预警)
        //Map<String, Object> monthWarnDay = dictionaryMapper.selectDicType("月检预警").get(0);
        //Integer warnDay =Integer.parseInt( monthWarnDay.get("dictValue").toString())
        SysConfigEntity sysConfigEntity = sysConfigMapper.selectByPrimaryKey(1);
        Integer warnDay = sysConfigEntity.getConfAlarmdate();

        //查到每台设备上次月检时间
        List<Map<String, Object>> equips = monthinspectionMapper.selectMonthWarnByEquipIds(equipIds);

        //筛出预警数据
        List<Map<String, Object>> warnData = getWarnData(warnDay, equips);
        warnNum = warnData.size();

        //筛出超时告警数据  复检时间<-当前时间 ?
        alarmNum = (int) warnData.stream()
                .filter((warn) -> {
                    Map<String, Object> equip = equipmentMapper.selectEquiDetail(Long.parseLong(warn.get("equipId").toString()));
                    return new Date().after(DateUtil.getString2Date(equip.get("certificateReexamine").toString()));
                }).count();

        vo.setEquipNum(list.size());
        vo.setWarnNum(warnNum);
        vo.setCheckNum(list.size() - warnNum);
        vo.setAlarmNum(alarmNum);
        return vo;
    }

    /**
     * 设备预警、告警分析
     *
     * @return
     */
    @Override
    public void AnaluEquipMonthAlarm() {
        //查到预警天数(指离上次多久预警)
        //Map<String, Object> monthWarnDay = dictionaryMapper.selectDicType("月检预警").get(0);
        //Integer warnDay =Integer.parseInt( monthWarnDay.get("dictValue").toString())
        SysConfigEntity sysConfigEntity = sysConfigMapper.selectByPrimaryKey(1);
        Integer warnDay = sysConfigEntity.getConfAlarmdate();

        //查到每台设备上次月检时间
        List<Map<String, Object>> equips = monthinspectionMapper.selectMonthWarnByEquipIds(null);

        //筛出预警数据
        List<Map<String, Object>> warnData = getWarnData(warnDay, equips);
        //筛出告警
        List<AlarmledgerEntity> collect = warnData.stream().filter((warn) -> {
                    Map<String, Object> equip = equipmentMapper.selectEquiDetail(Long.parseLong((String) warn.get("equipId")));
                    return new Date().after(DateUtil.getString2Date(equip.get("certificateReexamine").toString()));
                }).map(data -> {
                    AlarmledgerEntity entity = new AlarmledgerEntity();
                    entity.setEquipType((Long) data.get("equipTypeId"));
                    entity.setEquipId((Long) data.get("equipId"));
                    entity.setEquipNo((String) data.get("equipNo"));
                    entity.setAlarmType("月检");
                    entity.setAlarmContent("月检超时");
                    entity.setAlarmDate(LocalDateTime.now());
                    entity.setCreateTime(LocalDateTime.now());
                    entity.setUpdateTime(LocalDateTime.now());
                    return entity;
                })
                .collect(Collectors.toList());

        //查到在告警台账里已经存在并且时间小于30天的设备
        List<AlarmledgerEntity> alarmledgerEntities = alarmledgerMapper.selectCreateTimeMax();

        //去除这些设备
        collect.removeAll(alarmledgerEntities);

        //并加入告警台账
        alarmledgerMapper.insertList(collect);
    }

    private List<Map<String, Object>> getWarnData(Integer warnDay, List<Map<String, Object>> equips) {
        return equips.stream()
                .filter((time -> time.get("monthDate") != null))
                .filter((warn) -> {
                    //将上月时间转换为Date
                    Date stratDate = DateUtil.getString2Date(warn.get("monthDate").toString());
                    //比较当天时间与上次月检时间,判断是否大于设置时间,如果大于则预警
                    return DateUtil.getDiffDays(stratDate, DateUtil.getCurrentDate()) > warnDay;
                }).collect(Collectors.toList());
    }
}
